﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using Rung.Soft.Jx3Tookit.Addon.AutoPress.Utility;

namespace Rung.Soft.Jx3Tookit.Addon.AutoPress.Business
{
    /// <summary>
    /// 对一次完整工作的定义类。
    /// 包括工作的触发设置和工作任务。
    /// </summary>
    /// <remarks>
    /// 按照任务列表执行完一次完整的流程，算一次 Task。
    /// 执行完用户指令的所有内容，算一次 Job。
    /// </remarks>
    [Serializable]
    public class SkillJober : ISerializable, IDisposable
    {
        private bool syn_loop;// 通知信号：通知任务嵌套循环调用，从而形成任务的重复执行。
        public string Name;// 本工作的名称（界面称为项目名称）
        [NonSerialized]
        public bool IsBusy;// 是否在工作中
        public FireType FireType;// 激活本工作的方式
        public HotKey FireKey;// 激活本工作的按键
        public SkillTasker Tasker;// 本工作的任务

        [NonSerialized]
        public StartEndEvent OnJobStart;
        [NonSerialized]
        public StartEndEvent OnJobFinish;

        public SkillJober()
        {
            this.FireType = FireType.Sigle;
            this.Tasker = new SkillTasker();
            this.taskStart = () => { this.Tasker.Start(); };
            this.registStartNewOnFinish = () =>
            {
                this.Tasker.OnTaskFinish -= this.registStartNewOnFinish;

                if (syn_loop == true)
                {
                    this.Tasker.OnTaskFinish += this.registStartNewOnFinish;
                    this.Tasker.Start();
                }
                else
                    this.Stop();
            };
        }

        protected SkillJober(SerializationInfo info, StreamingContext context)
            : this()
        {
            this.Name = info.GetString("Name");
            this.FireType = (FireType)info.GetInt32("FireType");
            this.FireKey = HotKey.FromByte(info.GetByte("FireKey"));
            this.Tasker = info.GetValue("Tasker", typeof(SkillTasker)) as SkillTasker;
        }

        public void Start()
        {
            System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(InStart));
            t.Start();
        }

        private void InStart(object o)
        {
            this.IsBusy = true;
            this.syn_loop = false;
            this.Tasker.OnTaskFinish -= this.registStartNewOnFinish;

            if (this.FireType == FireType.Cycle)
            {
                this.syn_loop = true;
                this.Tasker.OnTaskFinish += this.registStartNewOnFinish;
            }
            else
            {
                this.syn_loop = false;
            }

            if (this.OnJobStart != null) this.OnJobStart();
            this.Tasker.Start();
            if (this.OnJobFinish != null) this.OnJobFinish();
        }

        public void Stop()
        {
            this.syn_loop = false;
            this.Tasker.OnTaskFinish -= this.registStartNewOnFinish;
            this.IsBusy = false;
        }

        [NonSerialized]
        private StartEndEvent taskStart;
        [NonSerialized]
        private StartEndEvent registStartNewOnFinish;// 若信号为继续循环，则在任务结束时注册开启新任务的指令，否则不开启。

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Name", this.Name);
            info.AddValue("FireType", this.FireType);
            info.AddValue("FireKey", this.FireKey.Key);
            info.AddValue("Tasker", this.Tasker);
        }

        public void Dispose()
        {
            if (this.IsBusy)
                this.Stop();
        }
    }
}
